package formulation;
import es.deusto.ingenieria.is.search.formulation.Operator;
import es.deusto.ingenieria.is.search.formulation.State;

public class MoverDisco extends Operator
{
	private int origen;
	private int destino;
	
	public MoverDisco(int origen, int destino)
	{
		super("Mover Disco del soporte '" + origen + "' al soporte '" + destino + "'" , 1d);
		this.origen = origen;
		this.destino = destino;
	}
	
	//Comprueba que el disco a mover de fuente sea menor al que haya en destino.
	@Override
	protected boolean isApplicable(State state) 
	{
		Environment environment = (Environment) state;
		Disco discOrigen = null;
		Disco discDestinoTop = null;
		
		if (!environment.getSoportes().get(this.origen - 1).getDiscos().isEmpty())
		{
			if (!environment.getSoportes().get(this.destino - 1).getDiscos().isEmpty())
			{
				discOrigen = environment.getSoportes().get(this.origen - 1).getDiscos().peek();
				//System.out.println(discOrigen.toString());
				discDestinoTop = environment.getSoportes().get(this.destino - 1).getDiscos().peek();
				//System.out.println(discDestinoTop.toString());
			}
			if (discDestinoTop != null)
			{
				return discOrigen.getSize() < discDestinoTop.getSize();
				
//				Tecnica del problema relajado
//				return true; 
			}
			else
			{
				return true;
			}
		}
		else
		{
			return false;
		}
	}

	@Override
	protected State effect(State state)
	{
		Environment newEnvironment = (Environment)((Environment) state).clone();
		System.out.println(newEnvironment.toString());
		Disco discOrigen = newEnvironment.getSoportes().get(this.origen - 1).getDiscos().pop();
		newEnvironment.getSoportes().get(this.destino - 1).getDiscos().push(discOrigen);
		return newEnvironment;
	}
	
	public int getOrigen()
	{
		return origen;
	}

	public void setOrigen(int origen) 
	{
		this.origen = origen;
	}

	public int getDestino() 
	{
		return destino;
	}

	public void setDestino(int destino)
	{
		this.destino = destino;
	}
	
//	public static void main(String[] args)
//	{
//		HanoiTowerProblem htp = new HanoiTowerProblem(3, 4, 1, 3);
//		MoverDisco md = new MoverDisco(1, 2);
//		
//		System.out.println("///////Soporte destino vacio");
//		
//		Environment environment = (Environment)htp.getInitialStates().get(0);
//		System.out.println("Soporte: " + environment.getSoportes().get(0).toString());
//		System.out.println("IsAplicable: " + md.isApplicable(htp.getInitialStates().get(0)));
//
//		System.out.println();
//		System.out.println("///////Soporte destino con disco peque�o en la pila");
//		
//		environment = (Environment)htp.getInitialStates().get(0);
//		environment.getSoportes().get(1).cargarDiscosSoporte(4);
//		System.out.println("Soporte: " + environment.getSoportes().get(0).toString());
//		System.out.println("IsAplicable: " + md.isApplicable(htp.getInitialStates().get(0)));
//		
//		System.out.println();
//		System.out.println("///////Soporte destino con disco grande en la pila");
//		
//		environment = (Environment)htp.getInitialStates().get(0);
//		environment.getSoportes().get(1).cargarDiscosSoporte(1);
//		environment.getSoportes().get(1).getDiscos().peek().setSize(3);
//		System.out.println("Soporte: " + environment.getSoportes().get(0).toString());
//		System.out.println("IsAplicable: " + md.isApplicable(htp.getInitialStates().get(0)));
		
//		System.out.println();
//		System.out.println("///////Efecto");
//		
//		System.out.println(htp.getInitialStates().get(0).toString());
//		System.out.println(md.effect(htp.getInitialStates().get(0)).toString());
//	}
}